package com.sywb.chuangyebao.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.support.v4.content.ContextCompat;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.method.LinkMovementMethod;
import android.text.style.ClickableSpan;
import android.text.style.ForegroundColorSpan;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.sywb.chuangyebao.Constants;
import com.sywb.chuangyebao.R;
import com.sywb.chuangyebao.bean.QARichInfo;

import org.bining.footstone.log.Logger;
import org.bining.footstone.utils.ScreenUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 富文本视图
 */
@SuppressLint("AppCompatCustomView")
public class RichTextView extends TextView {

    private static final int DEFAULT_LINK_HIGHLIGHT_COLOR = Color.parseColor("#4D6898");// 默认链接高亮颜色

    // 定义正则表达式
    private static final String AT = "@[\u4e00-\u9fa5\\w]+\\s";// @人（末尾含空格）
    private static final String TOPIC = "#[\u4e00-\u9fa5\\w]+#";// ##话题
    private static final String EMOJI = "\\[[\u4e00-\u9fa5\\w]+\\]";// 表情
    private static final String SUPERURL = "(((http|https)://)|((?<!((http|https)://))www\\.))" + ".*?" + "(?=(&nbsp;|[\\u4e00-\\u9fa5]|\\s|　|<br />|$|[<>]))";

    private static final String REGEX = "(" + AT + ")|(" + TOPIC + ")|(" + EMOJI + ")|(" + SUPERURL + ")";

    private String TEXT = "全文";

    private int mLinkHighlightColor = DEFAULT_LINK_HIGHLIGHT_COLOR;// 链接高亮的颜色，默认蓝色

    private HashMap<Integer, QARichInfo> richMap;

    private OnLinkClickListener mOnLinkClickListener;

    private boolean isExpandView = true;
    private boolean isExpandedOpen = false;

    private int deviationDP = R.dimen.dp_32;

    private String mOriginText;
    private int mViewWidth;
    private int expandedTextWidth;
    private int mLines = 3;

    private boolean isSearch = false;
    private String keyword;

    private int dataPostion;

    public RichTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView(context, attrs);
    }

    public RichTextView(Context context) {
        super(context);
        initView(context, null);
    }

    public void setSearch(boolean search) {
        isSearch = search;
    }

    public void setKeyword(String keyword) {
        this.keyword = keyword;
    }

    /**
     * 设置是否需要扩展【全文】
     */
    public void setExpandView(boolean expandView) {
        isExpandView = expandView;
    }

    public void setExpandText(String expandText) {
        this.TEXT = expandText;
    }

    /**
     * 设置扩展是否需要打开
     */
    public void setExpandedOpen(boolean expandedOpen) {
        isExpandedOpen = expandedOpen;
    }

    public void setDeviationDP(int deviationDP) {
        this.deviationDP = deviationDP;
    }

    /**
     * 设置列表数据的位置
     *
     * @param dataPostion
     */
    public void setDataPostion(int dataPostion) {
        this.dataPostion = dataPostion;
    }

    public int getDataPostion() {
        return dataPostion;
    }

    private void initView(Context context, AttributeSet attrs) {
        if (attrs != null) {
            TypedArray typedArray = getContext().obtainStyledAttributes(attrs, R.styleable.RichView);
            // 设置链接高亮颜色
            int mLinkHighlightColor = typedArray.getColor(R.styleable.RichView_linkHighlightColor, DEFAULT_LINK_HIGHLIGHT_COLOR);
            if (mLinkHighlightColor != 0) {
                setLinkHighlightColor(mLinkHighlightColor);
            }
            typedArray.recycle();
        }
        // 要实现文字的点击效果，这里需要做特殊处理
        setMovementMethod(new CustomLinkMovementMethod());
    }

    public void setRichText(String text, List<QARichInfo> richInfoList) {
        setRichData(richInfoList);
        setText(text);
    }

    @SuppressLint("UseSparseArrays")
    public void setRichData(List<QARichInfo> richInfoList) {
        if (richMap == null) {
            richMap = new HashMap<>();
        }

        if (richInfoList == null || richInfoList.size() == 0) {
            return;
        }

        for (QARichInfo richInfo : richInfoList) {

            Logger.e("richInfo:" + JSON.toJSONString(richInfo));

            if (richInfo == null || TextUtils.isEmpty(richInfo.richName)) {
                continue;
            }
            Logger.e("richInfo.position:" + richInfo.position + " richInfo.richName:" + richInfo.richName);
            for (int i = 0; i < richInfo.richName.length(); i++) {
                richMap.put(richInfo.position + i, richInfo);
            }
        }
    }

    public void setText(String text) {
        if (!TextUtils.isEmpty(text)) {
            if (isExpandView) {
                mViewWidth = getContentWidth();
                super.setText(formatCollapseText(text));
            } else {
                super.setText(getWeiboContent(text));
            }
        } else {
            super.setText("");
        }
    }

//    @Override
//    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//        if (isExpandView) {
//            int contentWidth = getContentWidth();
//            Logger.e("onMeasure > ContentWidth:" + contentWidth + " mViewWidth:" + mViewWidth);
//            if (mViewWidth != contentWidth) {
//                mViewWidth = contentWidth;
//                super.setText(formatCollapseText(mOriginText));
//            }
//        }
//    }

    private int getContentWidth() {
        int contentWidth = getMeasuredWidth() - getPaddingLeft() - getPaddingRight();
        if (contentWidth <= 0) {
            contentWidth = ScreenUtils.getScreenWidth() - (int) getContext().getResources().getDimension(deviationDP);
            Logger.e("未获取到控件宽度，默认为屏幕宽度：" + contentWidth);
        }
        return contentWidth;
    }

    /**
     * 格式化折叠时的文本
     */
    private SpannableString formatCollapseText(String text) {
        String data = text.replaceAll("[\\t\\n\\r]", " ");////将内容区域的回车换行去除

        // 获取 paint，用于计算文字宽度
        TextPaint paint = getPaint();

        int originTotleWidth = (int) paint.measureText(data);

        if (originTotleWidth <= (mViewWidth * mLines)) {
            isExpandView = false;
            return getWeiboContent(data);
        } else {
            this.mOriginText = data;

            if (expandedTextWidth == 0) {
                expandedTextWidth = (int) paint.measureText(TEXT);
            }

            List<String> listText = new ArrayList<>();
            for (int i = 0; i < data.length(); i++) {
                String chat = data.substring(i, i + 1);
                listText.add(i, chat);
            }

            // stringToList(listText, 0, data);

            StringBuilder dataBuilder = new StringBuilder();

            int lines = 1;
            float lineWidth = 0;
            float showWidth = 0;
            int ellipsizeLastIndex = 0;
            for (int i = 0; i < listText.size(); i++) {
                String chat = listText.get(i);
                float chatWidth = paint.measureText(chat);
                Logger.e("postion:" + i + " chat:" + chat + " chatWidth:" + chatWidth);
                lineWidth = lineWidth + chatWidth;

                if (lines < 4) {
                    int mLineWidth = mViewWidth;
                    if (lines == 3) {
                        mLineWidth = mViewWidth - expandedTextWidth;
                    }

                    if (lineWidth > mLineWidth) {
                        Logger.e("lines:" + lines + " lineWidth:" + (lineWidth - chatWidth));
                        showWidth = showWidth + lineWidth - chatWidth;
                        Logger.e("showWidth:" + showWidth);
                        lines += 1;
                        lineWidth = chatWidth;
                        ellipsizeLastIndex = i;
                        dataBuilder.append("\n");
                    }
                } else if (lines > 4) {
                    break;
                }
                dataBuilder.append(chat);
            }

            if (richMap != null && richMap.containsKey(ellipsizeLastIndex)) {
                QARichInfo richInfo = richMap.get(ellipsizeLastIndex);
                if (richInfo.position <= ellipsizeLastIndex) {
                    int delPosition = ellipsizeLastIndex - richInfo.position;
                    float delWidth = paint.measureText(richInfo.richName.substring(0, delPosition));
                    Logger.e("richMap delWidth:" + delWidth);
                    showWidth = showWidth - delWidth;
                }
            }

            CharSequence ellipsizeData = TextUtils.ellipsize(dataBuilder.toString(), paint, showWidth, TextUtils.TruncateAt.END);

            return getWeiboContent(ellipsizeData.toString() + Constants.SPACE + TEXT);
        }
    }

    public List<String> stringToList(List<String> listText, int index, String newText) {
        if (listText == null) {
            listText = new ArrayList<>();
        }
        if (newText == null || newText.equals("")) {
            return listText;
        }
        String chat = newText.substring(index, index + 1);
        listText.add(index, chat);
        index += 1;
        if (newText.length() > index) {
            return stringToList(listText, index, newText);
        }
        return listText;
    }

    /**
     * 设置微博内容样式
     */
    public SpannableString getWeiboContent(String source) {
        Logger.e("getWeiboContent:" + source);

        SpannableString spannableString = new SpannableString(source);

        if (isSearch) {
            List<Integer> indexs = new ArrayList<>();

            int index = source.indexOf(keyword);

            while (index >= 0) {
                Logger.e("source:" + source + " indexs" + index);
                indexs.add(index);
                index = index + keyword.length();
                index = source.indexOf(keyword, index);
            }


            for (int ind : indexs) {
                ForegroundColorSpan colorSpan = new ForegroundColorSpan(ContextCompat.getColor(getContext(), R.color.colorTheme));
                spannableString.setSpan(colorSpan, ind, ind + keyword.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }

        // 设置正则
        Pattern mPattern = Pattern.compile(REGEX);

        Matcher matcher = mPattern.matcher(spannableString);

        if (matcher.find()) {
            // 重置正则位置
            matcher.reset();
        }

        if (richMap != null && richMap.size() > 0) {

            Logger.e("richMap:" + richMap.size());

            while (matcher.find()) {
                // 根据group的括号索引，可得出具体匹配哪个正则(0代表全部，1代表第一个括号)
                String at = matcher.group(1);
                String topic = matcher.group(2);
                String emoji = matcher.group(3);
                String superurl = matcher.group(4);

                // 处理@符号
                if (at != null) {

                    // 获取匹配位置
                    int start = matcher.start(1);

                    Logger.e("at:" + at + " start:" + start);

                    if (richMap.containsKey(start)) {
                        QARichInfo richInfo = richMap.get(start);

                        Logger.e("richInfo:" + JSON.toJSONString(richInfo));

                        int lenght = richInfo.richName.length();
                        if (at.length() != richInfo.richName.length()) {
                            // lenght = Math.min(at.length(), richInfo.richName.length());
                            lenght = at.length();
                        }
                        int end = start + lenght;
                        MyClickableSpan clickableSpan = new MyClickableSpan(richInfo.uid) {

                            @Override
                            public void onClick(View v) {
                                if (mOnLinkClickListener != null) {
                                    mOnLinkClickListener.onAtClick(RichTextView.this, this.data);
                                }
                            }
                        };
                        spannableString.setSpan(clickableSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
                }

                // 处理话题##符号
                if (topic != null) {
                    int start = matcher.start(2);
                    if (richMap.containsKey(start)) {
                        QARichInfo richInfo = richMap.get(start);
                        int lenght = richInfo.richName.length();
                        if (topic.length() != richInfo.richName.length()) {
                            // lenght = Math.min(topic.length(), richInfo.richName.length());
                            lenght = topic.length();
                        }
                        int end = start + lenght;
                        MyClickableSpan clickableSpan = new MyClickableSpan(richInfo.uid) {

                            @Override
                            public void onClick(View v) {
                                if (mOnLinkClickListener != null) {
                                    mOnLinkClickListener.onTopicClick(RichTextView.this, this.data);
                                }
                            }
                        };
                        spannableString.setSpan(clickableSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    }
                }

                // 处理url地址
                if (superurl != null) {
                    int start = matcher.start(4);
                    int end = start + superurl.length();
                    MyClickableSpan clickableSpan = new MyClickableSpan(superurl) {

                        @Override
                        public void onClick(View v) {
                            if (mOnLinkClickListener != null) {
                                mOnLinkClickListener.onUrlClick(RichTextView.this, this.data);
                            }
                        }
                    };
                    spannableString.setSpan(clickableSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }

                if (emoji != null) {
                    int start = matcher.start(3);
                    int end = start + emoji.length();
                    MyClickableSpan clickableSpan = new MyClickableSpan(emoji) {

                        @Override
                        public void onClick(View v) {
                            if (mOnLinkClickListener != null) {
                                mOnLinkClickListener.onEmojiClick(RichTextView.this, this.data);
                            }
                        }
                    };
                    // int ResId = EmotionUtils.getImgByName(emoji);
                    // Bitmap bitmap =
                    // BitmapFactory.decodeResource(context.getResources(), ResId);
                    // if (bitmap != null) {
                    // // 获取字符的大小
                    // int size = (int) textView.getTextSize();
                    // // 压缩Bitmap
                    // bitmap = Bitmap.createScaledBitmap(bitmap, size, size, true);
                    // // 设置表情
                    // ImageSpan imageSpan = new ImageSpan(context, bitmap);
                    // spannableString.setSpan(imageSpan, start, end,
                    // Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                    // }
                    spannableString.setSpan(clickableSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }

            }
        }

        if (isExpandView) {
            int start = source.indexOf(TEXT);
            int end = start + TEXT.length();
            if (start > 0 && end == source.length()) {
                MyClickableSpan clickableSpan = new MyClickableSpan(null) {

                    @Override
                    public void onClick(View v) {
                        if (isExpandedOpen) {
                            isExpandView = false;
                            setText(mOriginText);
                        } else {
                            if (mOnLinkClickListener != null) {
                                mOnLinkClickListener.onAllClick(RichTextView.this);
                            }
                        }
                    }
                };
                spannableString.setSpan(clickableSpan, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }

        return spannableString;
    }

    public void setLinkHighlightColor(int mLinkHighlightColor) {
        this.mLinkHighlightColor = mLinkHighlightColor;
    }

    public int getLinkHightlightColor() {
        return this.mLinkHighlightColor;
    }

    public OnLinkClickListener getOnLinkClickListener() {
        return mOnLinkClickListener;
    }

    public void setOnLinkClickListener(OnLinkClickListener mOnLinkClickListener) {
        this.mOnLinkClickListener = mOnLinkClickListener;
    }

    /**
     * 继承ClickableSpan复写updateDrawState方法，自定义所需样式
     */
    private class MyClickableSpan extends ClickableSpan {

        public Object data;

        MyClickableSpan(Object data) {
            this.data = data;
        }

        @Override
        public void onClick(View v) {

        }

        @Override
        public void updateDrawState(TextPaint ds) {
            super.updateDrawState(ds);
            ds.setColor(mLinkHighlightColor);
            ds.setUnderlineText(false);
        }

    }

    /**
     * 链接点击的监听器
     */
    public interface OnLinkClickListener {
        /**
         * 点击了@的人， 如"@bining"
         */
        void onAtClick(RichTextView richTextView, Object userId);

        /**
         * 点击了话题，如"#中国#"
         */
        void onTopicClick(RichTextView richTextView, Object topicId);

        /**
         * 点击了表情
         */
        void onEmojiClick(RichTextView richTextView, Object emoji);

        /**
         * 点击了url，如"http://www.google.com"
         */
        void onUrlClick(RichTextView richTextView, Object url);

        /**
         * 点击了 全文
         */
        void onAllClick(RichTextView richTextView);
    }

    public class CustomLinkMovementMethod extends LinkMovementMethod {

        @Override
        public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
            boolean b = super.onTouchEvent(widget, buffer, event);
            //解决点击事件冲突问题
            if (!b && event.getAction() == MotionEvent.ACTION_UP) {
                ViewParent parent = widget.getParent();//处理widget的父控件点击事件
                if (parent instanceof ViewGroup) {
                    return ((ViewGroup) parent).performClick();
                }
            }
            return b;
        }
    }
}
